const Core = require('@alicloud/pop-core')
const tencentcloud = require('tencentcloud-sdk-nodejs')
const qiniu = require('qiniu')
const axios = require('axios')
const { ApiError } = require('../utils/error')

class SmsService {
  constructor() {
    this.client = null
    this.config = null
  }

  async initClient(config) {
    this.config = config
    
    switch (config.provider) {
      case 'aliyun':
        this.client = new Core({
          accessKeyId: config.accessKeyId,
          accessKeySecret: config.accessKeySecret,
          endpoint: 'https://dysmsapi.aliyuncs.com',
          apiVersion: '2017-05-25'
        })
        break
        
      case 'tencent':
        const TencentSmsClient = tencentcloud.sms.v20210111.Client
        this.client = new TencentSmsClient({
          credential: {
            secretId: config.secretId,
            secretKey: config.secretKey
          },
          region: 'ap-guangzhou',
          profile: {
            signMethod: 'HmacSHA256',
            httpProfile: {
              reqMethod: 'POST',
              reqTimeout: 30,
              endpoint: 'sms.tencentcloudapi.com'
            }
          }
        })
        break
        
      case 'qiniu':
        const mac = new qiniu.auth.digest.Mac(config.accessKey, config.secretKey)
        // 使用 axios 直接调用七牛云 API
        this.client = axios.create({
          baseURL: 'https://sms.qiniuapi.com/v1',
          headers: {
            'Content-Type': 'application/json'
          }
        })
        this.mac = mac
        break

      case 'huawei':
        this.client = axios.create({
          baseURL: 'https://smsapi.cn-north-4.myhuaweicloud.com:443',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        })
        break
        
      default:
        throw new ApiError(400, '不支持的短信服务商')
    }
  }

  async sendTestSms() {
    if (!this.client || !this.config) {
      throw new ApiError(400, '短信服务未初始化')
    }

    const testPhone = '13800138000'
    
    try {
      console.log('开始发送测试短信，配置信息:', {
        provider: this.config.provider,
        testPhone
      })
      
      switch (this.config.provider) {
        case 'aliyun':
          console.log('使用阿里云发送短信')
          await this.client.request('SendSms', {
            PhoneNumbers: testPhone,
            SignName: this.config.signName,
            TemplateCode: this.config.templateCode,
            TemplateParam: JSON.stringify({ code: '123456' })
          }, {
            method: 'POST'
          })
          break
          
        case 'tencent':
          console.log('使用腾讯云发送短信')
          await this.client.SendSms({
            PhoneNumberSet: [testPhone],
            SmsSdkAppId: this.config.appId,
            SignName: this.config.signContent,
            TemplateId: this.config.templateId,
            TemplateParamSet: ['123456']
          })
          break
          
        case 'qiniu':
          console.log('使用七牛云发送短信')
          const url = '/message/single'
          const data = {
            template_id: this.config.templateId,
            mobile: testPhone,
            parameters: {
              code: '123456'
            }
          }
          
          if (this.config.signatureId) {
            data.signature_id = this.config.signatureId
          }
          
          const method = 'POST'
          const path = `/v1${url}`
          const host = 'sms.qiniuapi.com'
          const contentType = 'application/json'
          const body = JSON.stringify(data)
          
          const signData = `${method} ${path}\nHost: ${host}\nContent-Type: ${contentType}\n\n${body}`
          
          const sign = qiniu.util.base64ToUrlSafe(qiniu.util.hmacSha1(signData, this.config.secretKey))
          
          const authorization = `Qiniu ${this.config.accessKey}:${sign}`
          
          await this.client.post(url, data, {
            headers: {
              'Authorization': authorization,
              'Content-Type': contentType,
              'Host': host
            }
          })
          break

        case 'huawei':
          console.log('使用华为云发送短信')
          const params = new URLSearchParams()
          params.append('from', this.config.channelNumber)
          params.append('to', testPhone)
          params.append('templateId', this.config.templateId)
          params.append('templateParas', JSON.stringify(['123456']))
          params.append('signature', this.config.signature)
          params.append('statusCallback', '')

          const headers = {
            'Authorization': `WSSE realm="SDP",profile="UsernameToken",type="Appkey"`,
            'X-WSSE': this.generateWsseHeader(this.config.appKey, this.config.appSecret)
          }

          await this.client.post('/sms/batchSendSms/v1', params, { headers })
          break
      }
    } catch (error) {
      console.error('发送测试短信失败:', {
        provider: this.config.provider,
        error: error.message,
        stack: error.stack,
        details: error.data || error.response || error
      })
      throw new ApiError(500, `发送失败: ${error.message}`)
    }
  }

  generateWsseHeader(appKey, appSecret) {
    const created = new Date().toISOString().replace(/.\d{3}Z$/, 'Z')
    const nonce = Math.random().toString(36).substring(2, 15)
    const passwordDigest = require('crypto')
      .createHash('sha256')
      .update(nonce + created + appSecret)
      .digest('base64')

    return `UsernameToken Username="${appKey}", PasswordDigest="${passwordDigest}", Nonce="${nonce}", Created="${created}"`
  }
}

module.exports = SmsService 